using System;
using System.Threading;

namespace Framework.Library.Core.Utils.Threading
{
    public sealed class CancelableAsyncResult : IAsyncResult
    {
        private readonly ManualResetEvent _cancelSignal;
        private bool _canceling;
        private IAsyncResult _result;

        public CancelableAsyncResult()
        {
            _cancelSignal = new ManualResetEvent(false);
        }

        internal IAsyncResult Result
        {
            get { return _result; }
            set { _result = value; }
        }

        internal ManualResetEvent CancelSignal
        {
            get { return _cancelSignal; }
        }

        internal bool Canceling
        {
            get { return _canceling; }
        }

        #region IAsyncResult Members

        public object AsyncState
        {
            get { return _result.AsyncState; }
        }

        public WaitHandle AsyncWaitHandle
        {
            get { return _result.AsyncWaitHandle; }
        }

        public bool CompletedSynchronously
        {
            get { return _result.CompletedSynchronously; }
        }

        public bool IsCompleted
        {
            get { return _result.IsCompleted; }
        }

        #endregion

        ~CancelableAsyncResult()
        {
            _cancelSignal.Close();
        }

        public void Cancel()
        {
            _canceling = true;
            _cancelSignal.Set();
        }
    }
}